﻿using System;
using System.Windows.Forms;
using DayWalker.GUI;
using DayWalker.Helpers;
using DayWalker.Core;
using DayWalker.Managers;
using DayWalker.Specialisation;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.TreeSharp;
using Styx.WoWInternals.WoWObjects;

namespace DayWalker
{
     
    public partial class Daywalker : CombatRoutine
    {
        public override sealed string Name { get { return "DayWalker Warlock ALWAYS Free"; } }
        public override WoWClass Class { get { return WoWClass.Warlock; } }
        public static LocalPlayer Me { get { return StyxWoW.Me; } }
        private static Daywalker Instance { get; set; }
        private Form _DayWalkerGui;
        internal event OnPulseHandler PulseEvent;
        internal delegate void OnPulseHandler();

        public override void Initialize()
        {
            TalentManager.Update(); // Update talents
            
           
            // Init Behaviours
            PreBuffSelector();
            RotationSelector();
            RestSelector();
            DeathSelector();
            Settings.DayWalkerSettings.Instance.UpdateStatus = true;

         //   if (!RebuildBehaviors())
          //  {
         //       return;
          //  }

            // PRINT OUT CLIENT LATENCY
            Log.Debug("Client Latency: {0}", StyxWoW.WoWClient.Latency);

            // PRINT OUT LAST RESTART TIME
            Log.Debug("{0:F1} days since Windows was started.", TimeSpan.FromMilliseconds(Environment.TickCount).TotalHours / 24.0);

            // PRINT OUT SETTINGS
            Settings.DayWalkerSettings.LogSettings();

            Logging.Write("Thanks for choosing DayWalker [FREE Version]! [ {0}]" );
            Logging.Write("You are a level {0} {1} ({2})", Me.Level, Me.Race, Me.IsAlliance ? "For the Alliance!" : "For the Horde!");

        }


        public Daywalker()
        {
            Instance = this;
        }

        public override void Pulse()
        {
            try
            {
                Spell.PulseDoubleCastEntries();
                OnPulseHandler handler = PulseEvent;

                if (handler != null)
                    handler();
            }
            catch (Exception ex)
            {
                
                Log.Debug("[Exception in Pulse: {0}]", ex);
            }
            if (!StyxWoW.IsInWorld ||
                !Helper.BasicCheck(Me))
            {
                return;
            }

            if (Settings.DayWalkerSettings.Instance.UpdateStatus)
            {
                Helper.UpdateStatus();
            } 
        }

        #region Extensions/Utilities
        #region Behaviors

        private Composite _combatBehavior, _preCombatBuffBehavior, _restBehavior, _deathBehavior;

        public override Composite CombatBehavior
        {
            get { return _combatBehavior; }
        }

        public override Composite PreCombatBuffBehavior
        {
            get { return _preCombatBuffBehavior; }
        }

        public override Composite RestBehavior
        {
            get { return _restBehavior; }
        }

        public override Composite DeathBehavior
        {
            get { return _deathBehavior; }
        }

        #endregion

        #region Buff & Rotation Selector

        private Composite PreBuffSelector()
        {
            if (_preCombatBuffBehavior == null)
            {
                Logging.Write("Initializing pre-combat buff behaviours.");
                _preCombatBuffBehavior = new PrioritySelector(Common.MainRotation());
            }
            return null;
        }

        private Composite RotationSelector()
        {
            if (_combatBehavior == null)
            {
                Logging.Write("Initializing combat behaviours.");
                _combatBehavior = new PrioritySelector(Common.MainRotation());
            }
            return null;
        }

        private Composite RestSelector()
        {
            if (_restBehavior == null)
            {
                Logging.Write("Initializing rest behaviours.");
                _restBehavior = new PrioritySelector(Helper.RestRotation());
            }
            return null;
        }

        private Composite DeathSelector()
        {
            if (_deathBehavior == null)
            {
                Logging.Write("Initializing death behaviours.");
                _deathBehavior = new PrioritySelector(DeathRotation());
            }
            return null;
        }


        private bool RebuildBehaviors()
        {
            try
            {
                Log.Debug("RebuildBehaviors called.");

                //_currentRotation = null; // clear current rotation


                if (_combatBehavior != null) _combatBehavior = new Decorator(ret => !StyxWoW.Me.Mounted && StyxWoW.Me.CurrentTarget != null && StyxWoW.Me.CurrentTarget.IsValid, new PrioritySelector(Common.MainRotation()));
                if (_preCombatBuffBehavior != null) _preCombatBuffBehavior = new Decorator(ret => !StyxWoW.Me.Mounted, new PrioritySelector(Common.MainRotation()));
                if (_deathBehavior != null) _deathBehavior = new Decorator(ret => !Me.Mounted, new PrioritySelector(DeathBehavior));

                return true;
            }
            catch (Exception ex)
            {
                Log.Debug("[RebuildBehaviors] Exception was thrown: {0}", ex);
                return false;
            }
        }
        #endregion

        public static void StopBot(string reason)
        {
            Log.Debug(reason);
            TreeRoot.Stop();
        }

        public override bool WantButton
        {
            get { return true; }
        }

        public override void OnButtonPress()
        {
            if (_DayWalkerGui == null || _DayWalkerGui.IsDisposed || _DayWalkerGui.Disposing) _DayWalkerGui = new ConfigurationForm();
            if (_DayWalkerGui != null || _DayWalkerGui.IsDisposed) _DayWalkerGui.ShowDialog();
        }
        #endregion

    }
}
